package com.eascs.banknet.boc.service.trans;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.jdom.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.banknet.boc.dao.BOC004Dao;
import com.eascs.banknet.boc.service.BOCAbstractService;
import com.eascs.banknet.common.entity.LoanUserEntity;
import com.eascs.banknet.common.utils.DESPlus;
import com.eascs.banknet.common.utils.XmlHelp;
import com.eascs.banknet.constant.EAContant;
import com.eascs.banknet.log.entity.LogEntity;
import com.eascs.common.util.StringUtil;

@Service("boc004Service")
public class BOC004Service extends BOCAbstractService {
	private static final Logger logger = LoggerFactory.getLogger(BOC004Service.class);

	private ExecutorService executorService = Executors.newFixedThreadPool(20);

	@Autowired
	private BOC004Dao boc004Dao;

	@Override
	public LogEntity initLogData() {
		LogEntity logEntity = new LogEntity();
		logEntity.setBankType(LogEntity.BANK_TYPE_BOC);
		logEntity.setTransType("004");
		logEntity.setTypeName("意见反馈");
		logEntity.setStartTime(new Date());
		return logEntity;
	}

	@Override
	public Map<String, String> dowork() {
		ServerSocket serverSocket = null;
		try {
			serverSocket = new ServerSocket(EAContant.BOC004_PORT);
			System.out.println("...............BOC004SocketServer服务启动................");
			while (true) {
				Socket socket = serverSocket.accept();
				logger.info("客户端连接成功,clientAddress:[{}]", socket.getRemoteSocketAddress());
				
				executorService.submit(new Runnable() {
					@Override
					public void run() {
						Reader reader = null;
						Writer writer = null;
						String appno = "";
						LogEntity logEntity = initLogData();
						try {
							reader = new InputStreamReader(socket.getInputStream(),"GBK");
							char chars[] = new char[8192 * 2];
							int n = reader.read(chars);
							String xml = DESPlus.getBocdecryptSubstr(new String(chars, 0, n), EAContant.BOC_DECODEKEY);
							logger.info("BOC004获取中行请求数据xml:[{}]完成" + xml);
							//XmlHelp.createXml("BOC004" + "(" + appno + ")", xml, "BOC004RQ", bocUtil.getEaFtpInfo());

							Element root = XmlHelp.getRootByString(xml);
							Element head = root.getChild("HEADER");
							String osn = head.getChildText("OSN");
							Element body = root.getChild("BODY");
							Element info = body.getChild("TRANLOG");
							if (null != info) {
								appno = info.getChildText("APPNO");
								String notation = info.getChildText("NOTATION");
								String type = info.getChildText("TYPE");
								StringBuilder validation = new StringBuilder("");
								if (StringUtil.isEmpty(appno)) {
									validation.append("[申请编号(APPNO) 不能为空]。  ");
								} else {
									if (getWordCount(appno) > 10) {
										validation.append("[申请编号(APPNO):" + appno + "]超出最大长度10。  ");
									}
								}
								if (StringUtil.isEmpty(notation)) {
									validation.append("[签署意见(NOTATION) 不能为空]。  ");
								} else {
									if (getWordCount(notation) > 2048) {
										validation.append("[签署意见(NOTATION):" + notation + "]超出最大长度2048。  ");
									}
								}
								if (StringUtil.isEmpty(type)) {
									validation.append("[意见类型(type) 不能为空]。  ");
								} else {
									if (getWordCount(type) > 1) {
										validation.append("[意见类型[(type):" + type + "]超出最大长度1。  ");
									}
								}
								if ("".equals(validation.toString())) {
									writeData(appno, xml);
									StringBuffer buffer = new StringBuffer("");
									buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append("<ROOT>").append("<HEADER>")
											.append("<RETCODE>" + "0000" + "</RETCODE>").append("<NOTE>" + "" + "</NOTE>")
											.append("<OSN>" + osn + "</OSN>").append("</HEADER>").append("<BODY>")
											.append("<INPUT><![CDATA[" + xml.toString() + "]]></INPUT>").append("</BODY>")
											.append("</ROOT>");
									//XmlHelp.createXml("004" + "(" + appno + ")", buffer.toString(), "BOC004RS", bocUtil.getEaFtpInfo());
									writer = new OutputStreamWriter(socket.getOutputStream());
									String returnXml = DESPlus.setBocencrypt(buffer.toString(), EAContant.BOC_DECODEKEY);
									writer.write(returnXml);
									writer.flush();
									logger.info("BOC004返回给中行消息:appNo:[{}],xml:[{}]", new Object[]{appno,buffer.toString()});
									logService.writeLog(logEntity, appno, LogEntity.RESULT_TYPE_SUCCESS, notation);
								} else {
									StringBuffer buffer = new StringBuffer("");
									buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append("<ROOT>").append("<HEADER>")
											.append("<RETCODE>" + "Error 1002  输入项校验失败：" + validation.toString() + "</RETCODE>")
											.append("<NOTE>Error 1002 xml</NOTE>").append("<OSN>" + osn + "</OSN>")
											.append("</HEADER>").append("<BODY>")
											.append("<INPUT><![CDATA[" + xml.toString() + "]]></INPUT>").append("</BODY>")
											.append("</ROOT>");
									//XmlHelp.createXml("004" + "(" + appno + ")", buffer.toString(), "BOC004RS", bocUtil.getEaFtpInfo());
									writer = new OutputStreamWriter(socket.getOutputStream());
									String returnXml = DESPlus.setBocencrypt(buffer.toString(), EAContant.BOC_DECODEKEY);
									writer.write(returnXml);
									writer.flush();
									logger.info("BOC004返回给中行消息:appNo:[{}],xml:[{}]", new Object[]{appno,buffer.toString()});
									logService.writeLog(logEntity, appno, LogEntity.RESULT_TYPE_ERROR, "Error 1002  输入项校验失败：" + validation.toString());
								}

							} else {
								writeData(null, xml);
								logger.info("BOC004返回给中行消息:appNo为空,xml:[{}]", new Object[]{appno,xml});
							}
						} catch (Exception e) {
							logService.writeLog(logEntity, appno, LogEntity.RESULT_TYPE_ERROR, e.getMessage());
							logger.error("BOC004返回给中行消息错误",e);
						} finally {
							try {
								reader.close();
								writer.close();
								socket.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				});
			}
		} catch (Exception e) {
			logger.error("BOC004监听服务异常，errMsg:[{}]", e);
		} 
		return null;
	}

	private void writeData(String appno, String xml) {
		if (StringUtil.hasText(appno)) {
			//XmlHelp.createXml("004" + "(" + appno + ")", xml, "BOC004RS", bocUtil.getEaFtpInfo());
			Element root = XmlHelp.getRootByString(xml);
			Element body = root.getChild("BODY");
			Element info = body.getChild("TRANLOG");
			appno = info.getChildText("APPNO");
			String notation = info.getChildText("NOTATION");
			notation = notation.replaceAll("null", "");
			String type = info.getChildText("TYPE");
			LoanUserEntity loanUserEntity = new LoanUserEntity();
			loanUserEntity.setBankApplyno(appno);
			loanUserEntity.setType(Integer.valueOf(type));
			loanUserEntity.setBackTime(new Date());
			loanUserEntity.setNotation(notation);
			boc004Dao.updateInfo(appno, notation, type);
		} else {
			Element root = XmlHelp.getRootByString(xml);
			Element body = root.getChild("BODY");
			Element info = body.getChild("TRANLOG");
			appno = info.getChildText("APPNO");
			//XmlHelp.createXml("FeedbackB01" + "(" + appno + ")", xml, "Feedback", bocUtil.getEaFtpInfo());
		}
	}

	/**
	 * 字符串长度
	 * 
	 * @param s
	 * @return
	 */
	public static int getWordCount(String s) {
		s = s.replaceAll("[^\\x00-\\xff]", "**");
		int length = s.length();
		return length;
	}
}
